import { useEffect, useState } from 'react';

import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { type FormInstance } from 'antd';

import { DataTypeList, objToArray } from '@/constants';

/**
 * 枚举项接口
 */
interface EnumItem {
  value: string;
  desc: string;
}

/**
 * 数据类型组件配置常量
 */
const DATA_TYPE_CONSTANTS = {
  MAX_ENUM_ITEMS: 100,
  MIN_ENUM_ITEMS: 1,
  MAX_ARRAY_ELEMENTS: 10,
  DEFAULT_DATA_LEN_UNIT: '字符',
  DATE_FORMAT_PLACEHOLDER: '整数类型Int64的UTC时间戳(毫秒)',
} as const;

/**
 * 数据类型组件属性
 */
interface DataTypeComponentProps {
  form: FormInstance;
  dataType: string;
  readonly?: boolean;
}

/**
 * 数据类型配置组件
 */
const DataTypeComponent = ({
  form,
  dataType,
  readonly: _readonly = false,
}: DataTypeComponentProps) => {
  // 枚举项状态
  const [enumItems, setEnumItems] = useState<EnumItem[]>([{ value: '', desc: '' }]);

  // 数据类型配置映射
  const dataTypeConfig = {
    number: ['int32', 'int64', 'float', 'double'],
    enum: ['enum'],
    bool: ['bool'],
    dataLen: ['string', 'file', 'password', 'geopoint'],
    array: ['array'],
    date: ['date', 'datetime'],
  };

  // 判断数据类型的工具函数
  const isDataType = (type: keyof typeof dataTypeConfig) => dataTypeConfig[type].includes(dataType);

  // 各种类型判断
  const isNumberType = isDataType('number');
  const isEnumType = isDataType('enum');
  const isBoolType = isDataType('bool');
  const needDataLen = isDataType('dataLen');
  const isArrayType = isDataType('array');
  const isDateType = isDataType('date');

  // 枚举项操作的通用同步函数
  const syncEnumItemsToForm = (newItems: EnumItem[]) => {
    setEnumItems(newItems);
    form.setFieldValue('domains', newItems);
  };

  // 添加枚举项
  const addEnumItem = () => {
    if (enumItems.length >= DATA_TYPE_CONSTANTS.MAX_ENUM_ITEMS) {
      window.$message.warning(`最多支持${DATA_TYPE_CONSTANTS.MAX_ENUM_ITEMS}个枚举项`);
      return;
    }
    const newItems = [...enumItems, { value: '', desc: '' }];
    syncEnumItemsToForm(newItems);
  };

  // 删除枚举项
  const removeEnumItem = (index: number) => {
    if (enumItems.length <= DATA_TYPE_CONSTANTS.MIN_ENUM_ITEMS) {
      window.$message.warning('至少保留一个枚举项');
      return;
    }
    const newItems = enumItems.filter((_, i) => i !== index);
    syncEnumItemsToForm(newItems);
  };

  // 更新枚举项
  const updateEnumItem = (index: number, field: keyof EnumItem, value: string) => {
    const newItems = [...enumItems];
    newItems[index][field] = value;
    syncEnumItemsToForm(newItems);
  };

  // 清空所有特殊字段的通用函数
  const clearAllFields = () => {
    const fieldsToReset = {
      domains: [],
      boolT: '',
      boolF: '',
      dataLen: '',
      dataLenUnit: DATA_TYPE_CONSTANTS.DEFAULT_DATA_LEN_UNIT,
      arrayDataType: '',
      len: '',
      min: '',
      max: '',
      step: '',
      unit: '',
      dateFormat: '',
    };

    Object.entries(fieldsToReset).forEach(([field, value]) => {
      form.setFieldValue(field, value);
    });
  };

  // 监听数据类型变化，同步相关字段
  useEffect(() => {
    // 先清空所有字段
    clearAllFields();

    // 根据类型设置特定字段
    if (isEnumType) {
      const currentDomains = form.getFieldValue('domains');
      if (!currentDomains || currentDomains.length === 0) {
        form.setFieldValue('domains', enumItems);
      } else {
        // 如果已有数据，同步到 enumItems 状态
        setEnumItems(currentDomains);
      }
    } else if (needDataLen) {
      // 数据长度类型保持默认单位
      form.setFieldValue('dataLenUnit', DATA_TYPE_CONSTANTS.DEFAULT_DATA_LEN_UNIT);
    }
  }, [isEnumType, isBoolType, needDataLen, isArrayType, isDateType, dataType, form, enumItems]);

  return (
    <>
      {/* 隐藏的 domains 字段，用于接收枚举数据 */}
      <AForm.Item name="domains" hidden>
        <AInput />
      </AForm.Item>

      {/* 数据类型选择 */}
      <ACol span={24}>
        <AForm.Item
          name="dataType"
          label="数据类型"
          rules={[{ required: true, message: '请选择数据类型' }]}
        >
          <ASelect options={objToArray(DataTypeList)}></ASelect>
        </AForm.Item>
      </ACol>

      {/* 布尔类型配置 */}
      {isBoolType && (
        <>
          <ACol span={12}>
            <AForm.Item
              name="boolT"
              label="true值"
              rules={[{ required: true, message: '请输入true对应的值' }]}
            >
              <AInput addonBefore="true " placeholder="请输入true对应的值" />
            </AForm.Item>
          </ACol>
          <ACol span={12}>
            <AForm.Item
              name="boolF"
              label="false值"
              rules={[{ required: true, message: '请输入false对应的值' }]}
            >
              <AInput addonBefore="false" placeholder="请输入false对应的值" />
            </AForm.Item>
          </ACol>
        </>
      )}

      {/* 数组类型配置 */}
      {isArrayType && (
        <ACol span={24}>
          <ARow gutter={8}>
            <ACol span={12}>
              <AForm.Item
                name="arrayDataType"
                label="元素类型"
                rules={[{ required: true, message: '请选择元素类型' }]}
              >
                <ASelect
                  placeholder="请选择元素类型"
                  options={objToArray(DataTypeList).filter(
                    option => option.value !== 'array' && option.value !== 'enum'
                  )}
                />
              </AForm.Item>
            </ACol>
            <ACol span={12}>
              <AForm.Item
                name="len"
                label="元素个数"
                rules={[
                  { required: true, message: '请输入元素个数' },
                  { pattern: /^[1-9]\d*$/, message: '请输入正整数' },
                  {
                    validator: (_, value) => {
                      if (value && parseInt(value) > DATA_TYPE_CONSTANTS.MAX_ARRAY_ELEMENTS) {
                        return Promise.reject(
                          new Error(`元素最大支持${DATA_TYPE_CONSTANTS.MAX_ARRAY_ELEMENTS}个`)
                        );
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
                <AInput placeholder={`元素最大支持${DATA_TYPE_CONSTANTS.MAX_ARRAY_ELEMENTS}个`} />
              </AForm.Item>
            </ACol>
          </ARow>
        </ACol>
      )}

      {/* 数据长度配置 */}
      {needDataLen && (
        <ACol span={24}>
          <ARow gutter={8}>
            <ACol span={18}>
              <AForm.Item
                name="dataLen"
                label="数据长度"
                rules={[{ required: true, message: '请输入数据长度' }]}
              >
                <AInput placeholder="整数最大256,单位：字符" />
              </AForm.Item>
            </ACol>
            <ACol span={6}>
              <AForm.Item
                name="dataLenUnit"
                label=" "
                colon={false}
                initialValue={DATA_TYPE_CONSTANTS.DEFAULT_DATA_LEN_UNIT}
              >
                <ASelect
                  options={[
                    {
                      label: DATA_TYPE_CONSTANTS.DEFAULT_DATA_LEN_UNIT,
                      value: DATA_TYPE_CONSTANTS.DEFAULT_DATA_LEN_UNIT,
                    },
                  ]}
                />
              </AForm.Item>
            </ACol>
          </ARow>
        </ACol>
      )}

      {/* 枚举类型配置 */}
      {isEnumType && (
        <ACol span={24}>
          <div style={{ marginBottom: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', marginBottom: 8 }}>
              <span style={{ fontWeight: 'bold' }}>枚举项</span>
              <span style={{ color: '#999', marginLeft: 8, fontSize: '12px' }}>
                最多{DATA_TYPE_CONSTANTS.MAX_ENUM_ITEMS}项
              </span>
            </div>

            {enumItems.map((item, index) => (
              <div
                key={index}
                style={{ display: 'flex', gap: 8, marginBottom: 8, alignItems: 'flex-start' }}
              >
                <div style={{ flex: 1 }}>
                  <AInput
                    placeholder="参数值"
                    value={item.value}
                    onChange={e => updateEnumItem(index, 'value', e.target.value)}
                  />
                </div>
                <div style={{ flex: 2 }}>
                  <AInput
                    placeholder="参数描述"
                    value={item.desc}
                    onChange={e => updateEnumItem(index, 'desc', e.target.value)}
                  />
                </div>
                {enumItems.length > 1 && (
                  <AButton
                    type="text"
                    danger
                    icon={<MinusCircleOutlined />}
                    onClick={() => removeEnumItem(index)}
                    style={{ flexShrink: 0 }}
                  />
                )}
              </div>
            ))}

            <AButton
              type="dashed"
              onClick={addEnumItem}
              icon={<PlusOutlined />}
              style={{ width: '100%', marginTop: 8 }}
              disabled={enumItems.length >= DATA_TYPE_CONSTANTS.MAX_ENUM_ITEMS}
            >
              添加枚举项
            </AButton>
          </div>
        </ACol>
      )}

      {/* 数字与数组类型配置 */}
      {(isNumberType || isArrayType) && (
        <>
          <ACol span={12}>
            <AForm.Item
              name="min"
              label="取值范围(最小值)"
              rules={[{ required: true, message: '请输入最小值' }]}
            >
              <AInput placeholder="请输入最小值" allowClear></AInput>
            </AForm.Item>
          </ACol>
          <ACol span={12}>
            <AForm.Item
              name="max"
              label="取值范围(最大值)"
              rules={[{ required: true, message: '请输入最大值' }]}
            >
              <AInput placeholder="请输入最大值" allowClear></AInput>
            </AForm.Item>
          </ACol>
          <ACol span={12}>
            <AForm.Item
              name="step"
              label="步长"
              rules={[{ required: false, message: '请输入步长' }]}
            >
              <AInput placeholder="请输入步长" allowClear></AInput>
            </AForm.Item>
          </ACol>
          <ACol span={12}>
            <AForm.Item
              name="unit"
              label="单位"
              rules={[{ required: false, message: '请输入单位' }]}
            >
              <AInput placeholder="请输入单位" allowClear></AInput>
            </AForm.Item>
          </ACol>
        </>
      )}

      {/* 时间类型配置 */}
      {isDateType && (
        <ACol span={24}>
          <AForm.Item
            label="时间格式"
            name="dateFormat"
            rules={[{ required: false, message: '请选择开始时间' }]}
          >
            <AInput disabled placeholder={DATA_TYPE_CONSTANTS.DATE_FORMAT_PLACEHOLDER}></AInput>
          </AForm.Item>
        </ACol>
      )}
    </>
  );
};

export default DataTypeComponent;
